use serde::de::{MapAccess, Visitor};
use serde::{Deserialize, Deserializer};
use std::collections::HashMap;
use std::io;
use std::{fmt, fs};

/// 从json文件读取数据
pub fn read_json_file() -> DataGroups {
    let json_path = "district.json";
    let file = fs::File::open(json_path).unwrap();
    let reader = io::BufReader::new(file);

    serde_json::from_reader(reader).unwrap()
}

/// 反序列化有重复键的, 值为数组的json.
/// 同一个键的所有值都会被合并.
fn duplicated_map<'de, D>(deserializer: D) -> Result<HashMap<String, Vec<String>>, D::Error>
where
    D: Deserializer<'de>,
{
    struct DuplicatedMapVisitor;

    impl<'de> Visitor<'de> for DuplicatedMapVisitor {
        type Value = HashMap<String, Vec<String>>;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("a map with duplicated string keys and array string values")
        }

        fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
        where
            A: MapAccess<'de>,
        {
            let mut data = HashMap::new();

            // 合并
            while let Some((key, value)) = map.next_entry::<String, Vec<String>>()? {
                data.entry(key).or_insert_with(Vec::new).extend(value);
            }

            Ok(data)
        }
    }

    deserializer.deserialize_map(DuplicatedMapVisitor)
}

#[derive(Debug, Deserialize)]
pub struct DataGroups {
    #[serde(flatten)]
    pub groups: HashMap<String, CityData>,
}

#[derive(Debug, Deserialize)]
pub struct CityData {
    #[serde(flatten)]
    #[serde(deserialize_with = "duplicated_map")]
    pub city_map: HashMap<String, Vec<String>>,
}
